#include "gui_app_main.h"

/**********************
 *  GLOBAL PROTOTYPES
 **********************/
lv_obj_t         *gui_app_current_obj = NULL;    /* 指向当前APP的obj指针, NULL表示停留在桌面 */
volatile uint8_t cur_tab_idx          = 0;       /* 更新tabview的索引，用于返回桌面时保持原来的位置 */

/*********************************************** APP 相关 ***********************************************/

/* 保app的对象的链表结构 */
typedef struct APP_OBJ_LIST
{
    lv_obj_t            *obj;
    struct APP_OBJ_LIST *next;
} app_obj_list_t;

app_obj_list_t * app_obj_list = NULL;

/**
* @brief app追加list
* @param obj-list对象
* @retval   None
* @note 在链表结尾添加
*/
static void s_gui_app_obj_list_append(lv_obj_t *obj)
{
    if (app_obj_list == NULL)       /* 链表为空时 */
    {
        app_obj_list       = (app_obj_list_t *) lv_mem_alloc(sizeof (app_obj_list_t));
        app_obj_list->next = NULL;
        app_obj_list->obj  = obj;
    }
    else                            /* 链表不为空时 */
    {
        app_obj_list_t *p    = app_obj_list;
        app_obj_list_t *node = (app_obj_list_t *) lv_mem_alloc(sizeof (app_obj_list_t));

        while (p)
        {
            if (p->next == NULL)
            {
                p->next    = node;
                node->next = NULL;
                node->obj  = obj;
            }

            p = p->next;
        }
    }

    return;
}

/* 桌面提示信息框处理函数 */
static void s_gui_desktop_notice_mbox_event_cb(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t * msgbox = lv_event_get_current_target(e);

    /* 校验有效性 */
    if (msgbox == NULL)
    {
        return;
    }

    if (code == LV_EVENT_PRESSED)
    {
        const char * txt = lv_msgbox_get_active_btn_text(msgbox);

        if(strcmp(txt, "apply") == 0)  /* 匹配上 'apply' */
        {
            lv_msgbox_close(msgbox);    /* 关闭 */
        }
        else if (strcmp(txt, "close") == 0) /* 匹配上 'close' */
        {
            lv_msgbox_close(msgbox);    /* 关闭 */
        }
    }

    return;
}

/* 屏幕顶部状态栏区域 */
static void s_gui_desktop_top_status_area(lv_obj_t * parent)
{
    static lv_style_t obj_layout_style;   // 容器的样式

    /* 样式初始化 */
    lv_style_init(&obj_layout_style);
    lv_style_set_pad_all(&obj_layout_style, 0);
    lv_style_set_bg_opa(&obj_layout_style, LV_OPA_0);
    lv_style_set_border_opa(&obj_layout_style, LV_OPA_0);
    //lv_style_set_text_font(&obj_layout_style, &lv_font_montserrat_16);
    //lv_style_set_radius(&obj_layout_style, 0);
    lv_style_set_text_color(&obj_layout_style, lv_color_hex(0xffffff));

    /* Layout 初始化 */
    lv_obj_t * panel = lv_obj_create(parent);
    lv_obj_set_size(panel,  LV_PCT(100), GUI_TOP_STATUS_PANEL_HEIGHT);       /* 大小 */
    lv_obj_add_style(panel, &obj_layout_style, 0);
    lv_obj_align(panel, LV_ALIGN_TOP_MID, 0, 5);
    lv_obj_set_scrollbar_mode(panel, LV_SCROLLBAR_MODE_OFF);                /* 隐藏滚动条 */

    /* 右上角状态图标显示 */
    lv_obj_t * panel_icon = lv_obj_create(panel);
    lv_obj_set_size(panel_icon, 200, GUI_TOP_STATUS_PANEL_HEIGHT);
    lv_obj_set_layout(panel_icon, LV_LAYOUT_FLEX);
    lv_obj_set_style_base_dir(panel_icon, LV_BASE_DIR_RTL, 0); /* 子部件排列顺序: 从右至左 */
    lv_obj_set_flex_flow(panel_icon, LV_FLEX_FLOW_ROW);
    lv_obj_align(panel_icon, LV_ALIGN_RIGHT_MID, 0, 0);
    lv_obj_add_style(panel_icon, &obj_layout_style, 0);

    lv_obj_t * label = lv_label_create(panel_icon);
    lv_label_set_text(label,  " ");

    /* 电池图标 */
    lv_obj_t * label_bat = lv_label_create(panel_icon);
    lv_label_set_text(label_bat, LV_SYMBOL_BATTERY_3);

    /* wifi图标 */
    lv_obj_t * label_wifi = lv_label_create(panel_icon);
    lv_label_set_text(label_wifi, LV_SYMBOL_WIFI);

    /* bluetooth图标 */
    lv_obj_t * label_bluetooth = lv_label_create(panel_icon);
    lv_label_set_text(label_bluetooth, LV_SYMBOL_BLUETOOTH);

    /* 时间栏 */
    lv_obj_t * label_time = lv_label_create(panel);
    lv_label_set_text(label_time, "  ");
    lv_obj_align(label_time, LV_ALIGN_LEFT_MID, 0, 0);

    /* test */
    lv_label_set_text_fmt(label_time, "   %02d:%02d  %04d-%02d-%02d",
                          16, 20, 2022, 5, 16);

    return;
}

/**
* @brief 退出APP
* @retval    None
*/
static void s_gui_app_btn_back_event_cb(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t * obj = lv_event_get_target(e);
    void *user_data = lv_event_get_user_data(e);

    if (code == LV_EVENT_PRESS_LOST)
    {

    }
    else if (code == LV_EVENT_PRESSED)
    {

    }
    else if (code == LV_EVENT_CLICKED)
    {
        /* 当前app指针为NULL */
        gui_app_current_obj = NULL;

        /* 标记app被销毁 */
        if (user_data != NULL)
        {
            ((app_status_ctrl_t) user_data)(GUI_APP_DESTROIED); /* 有的APP需要知道自身的状态 */
        }

        /* 退出窗口 */
        lv_obj_del(lv_obj_get_parent(obj));
    }

    return;
}

/**
* @brief APP公用初始化
* @param parent-父对象
* @param title-APP标题
* @retval   创建的APP的对象
*/
lv_obj_t * gui_app_common_init(lv_obj_t *parent, const char *title, app_status_ctrl_t app_status_ctrl)
{
    static lv_style_t style_btn_back;

    lv_style_init(&style_btn_back);           // 初始化按钮样式
    lv_style_set_radius(&style_btn_back, 22); // 设置样式圆角弧度

    /* 创建一个obj */
    lv_obj_t *obj = lv_obj_create(parent);
    lv_obj_set_size(obj, LV_HOR_RES, LV_VER_RES);

    /* 创建一个返回按键 */
    lv_obj_t *btn_back = lv_btn_create(obj);
    lv_obj_set_size(btn_back, 60, 50);
    lv_obj_align(btn_back, LV_ALIGN_TOP_LEFT, 10, 10);
    lv_obj_add_style(btn_back, &style_btn_back, 0);
    lv_obj_add_event_cb(btn_back, s_gui_app_btn_back_event_cb, LV_EVENT_ALL, (void *) app_status_ctrl); /* 用户参数是一个函数 */

    /* 创建一个label */
    lv_obj_t *label_back = lv_label_create(btn_back);
    lv_label_set_text(label_back, LV_SYMBOL_LEFT);
    lv_obj_align_to(label_back, btn_back, LV_ALIGN_CENTER, 0, 0);

    /* 显示title */
    lv_obj_t *label_title = lv_label_create(obj);
    lv_label_set_text(label_title, title);
    lv_obj_align(label_title, LV_ALIGN_TOP_MID, 0, 0);

    /* 设置app是被创建的状态 */
    if (app_status_ctrl != NULL)
    {
        app_status_ctrl(GUI_APP_CREATED);   /* 有的APP需要知道自身的状态 */
    }

    /* 返回该对象 */
    return obj;
}

/**
* @brief APP空函数
* @param user_data-自定义数据
* @retval    None
*/
static lv_obj_t * gui_app_create_null(lv_obj_t *parent, void *user_data)
{
    (void) user_data;
    (void) parent;

    static lv_style_t msgbox_style;
    lv_style_init(&msgbox_style);          // 初始化按钮样式
    lv_style_set_radius(&msgbox_style, 22); // 设置样式圆角弧度

    static const char * btns[] ={"apply", "close", ""};

    lv_obj_t * notice_mbox = lv_msgbox_create(NULL, \
                                              "App Error", \
                                              "I don't want to do it right now unless you give me money.", \
                                              btns, false);

    if (notice_mbox != NULL)
    {
        lv_obj_add_style(notice_mbox, &msgbox_style, 0);
        lv_obj_align(notice_mbox, LV_ALIGN_CENTER, 0, 0);
        lv_obj_add_event_cb(notice_mbox, s_gui_desktop_notice_mbox_event_cb, LV_EVENT_PRESSED, NULL);
    }

    return NULL;
}

/* APP函数声明 */
extern lv_obj_t * gui_app_led_create(lv_obj_t *parent, void *user_data);
extern lv_obj_t * gui_app_axis_create(lv_obj_t *parent, void *user_data);
extern lv_obj_t * gui_app_beep_create(lv_obj_t *parent, void *user_data);
extern lv_obj_t * gui_app_dial_create(lv_obj_t *parent, void *user_data);

/* 桌面页和其图标 */
static const app_icon_item_t app_desktop_icons[GUI_APP_TAB_NBR][GUI_APP_NBR_PER_TAB] = 
{
    /* page1 */
    {
        {&icon_led_main, "led", NULL, gui_app_led_create},
        {&icon_camera_main, "axis", NULL, gui_app_axis_create},
        {&icon_clock_main, "dial", NULL, gui_app_dial_create},
        {&icon_set_main, "set", NULL, gui_app_create_null},
        {&icon_picture_main, "picture", NULL, gui_app_create_null},
        {&icon_game_main, "game", NULL, gui_app_create_null},
        {&icon_led_main, "led", NULL, gui_app_create_null},
        {&icon_camera_main, "camera", NULL, gui_app_create_null},
        {&icon_clock_main, "clock", NULL, gui_app_create_null},
        {&icon_set_main, "set", NULL, gui_app_create_null},
        {&icon_picture_main, "picture", NULL, gui_app_create_null},
        {&icon_game_main, "game", NULL, gui_app_create_null},
        {&icon_led_main, "led", NULL, gui_app_create_null},
        {&icon_camera_main, "camera", NULL, gui_app_create_null},
        {&icon_clock_main, "clock", NULL, gui_app_create_null},
        {&icon_set_main, "set", NULL, gui_app_create_null},
        {&icon_picture_main, "picture", NULL, gui_app_create_null},
        {&icon_game_main, "game", NULL, gui_app_create_null},
    },

    /* page2 */
    {
        {&icon_caculator_main, "caculator", NULL, gui_app_create_null}
    },

    /* page3 */
    {
        {&icon_compass_main, "compass", NULL, gui_app_create_null}
    }
};

/* 固定app和其图标 */
static const app_icon_item_t app_panel_icons[] = 
{
    {&icon_led_main, "led", NULL, gui_app_led_create},
    {&icon_camera_main, "camera", NULL, gui_app_led_create},
    {&icon_clock_main, "clock", NULL, gui_app_led_create},
    {&icon_set_main, "set", NULL, gui_app_led_create}
};

/**
* @brief ICON的事件回调函数
* @param event-事件类型
* @retval    None
* @note 根据对象找链表中的索引,根据索引执行APP
*/
static void s_gui_app_obj_event_cb(lv_event_t *e)
{
    uint8_t  j, k;
    uint16_t i = 0, m_c = 0, m_l = 0;
    uint8_t  page_app_nbr[GUI_APP_TAB_NBR] = {0};

    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t * obj = lv_event_get_target(e);

    if (code == LV_EVENT_CLICKED)
    {
        app_obj_list_t * p = app_obj_list;

        /* 在 obj链表 中匹配 obj */
        while (p)
        {
            if (p->obj == obj)
            {
                break;
            }
            i++;
            p = p->next;
        }

        /* 计算每页的app个数 */
        for (j = 0; j < GUI_APP_TAB_NBR; j++)
        {
            for (k = 0; k < GUI_APP_NBR_PER_TAB; k++)
            {
                /* 判断成员是否有效 */
                if ((app_desktop_icons[j][k].img == NULL) || (app_desktop_icons[j][k].app_create == NULL))
                {
                    break;  /* 当前页面创建完成 */
                }
            }

            page_app_nbr[j] = k;    /* 记录第j页的app个数 */
        }

        /* 找到要启动的app并启动 */
        for (j = 0; j < GUI_APP_TAB_NBR; j++)
        {
            m_l =  m_c;                 /* m_l: 每页第一个应用图标在链表中的序号 */
            m_c += page_app_nbr[j];     /* m_c: 每页最后一个应用图标在链表中的序号 */

            if (i < m_c)
            {
                /* 定位到要启动的app, 并启动 */
                gui_app_current_obj = app_desktop_icons[j][i - m_l].app_create(lv_scr_act(), NULL);

                /* 跳出循环 */
                break;
            }
        }
    }

    return;
}

/*********************************************** 函数 相关 ***********************************************/

/* 滑动到最后/最前一页时, 页面循环切换(无限切换) */
static void s_gui_tab_scroll_end_handler(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t        *obj = lv_event_get_target(e);
    lv_obj_t        *tv  = lv_obj_get_parent(obj);    

    if (code == LV_EVENT_SCROLL_END)
    {
        rt_kprintf("s_gui_tab_scroll_end_handler\r\n");
        lv_tabview_t *tabview = (lv_tabview_t *) tv;
        lv_coord_t          x = lv_obj_get_scroll_x(obj);
        lv_point_t          p;

        lv_obj_get_scroll_end(obj, &p);

        lv_coord_t w = lv_obj_get_content_width(obj);
        lv_coord_t t;

        if (lv_obj_get_style_base_dir(tv, LV_PART_MAIN) == LV_BASE_DIR_RTL)
        {
            t = -(p.x - w / 2) / w;
        }
        else 
        {
            t = (p.x + w / 2) / w;
        }

        if (x < 0)
        {
            t = tabview->tab_cnt - 1;
        }
        else if((t == (tabview->tab_cnt - 1)) && (x > p.x))
        {
            t = 0;
        }

        lv_tabview_set_act(tv, t, LV_ANIM_ON);
    }
    
    return;
}

/* tabview被改变后记录当前tab序号 */
static void s_gui_tab_idx_event_handler(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t        *obj = lv_event_get_target(e);

    if (code == LV_EVENT_VALUE_CHANGED)
    {
        if (obj != NULL)
        {
            cur_tab_idx = lv_tabview_get_tab_act(obj);  /* 获得当前的 tab序号 */
        }
        else
        {
            cur_tab_idx = 0;
        }
    }
    
    return;
}

/* 创建提示当前tab的提示圆点 */
static void s_gui_tab_idx_dot_create(lv_obj_t * parent, int idx)
{
    uint8_t  i;
    lv_obj_t *round[3];

    /* 左菜单指示 */
    round[0] = lv_obj_create(parent);       /* 左边 */
    lv_obj_set_style_border_opa(round[0], LV_OPA_0, 0);
    lv_obj_set_size(round[0], 8, 8);      /* 设置提示圈大小 */
    lv_obj_align(round[0], LV_ALIGN_CENTER, -20, 150);  /* 距离中心点的相对位置 */

    round[1] = lv_obj_create(parent);       /* 中间 */
    lv_obj_set_style_border_opa(round[1], LV_OPA_0, 0);
    lv_obj_set_size(round[1], 8, 8);      /* 设置提示圈大小 */
    lv_obj_align(round[1], LV_ALIGN_CENTER, 0, 150);    /* 距离中心点的相对位置 */

    round[2] = lv_obj_create(parent);       /* 右边 */
    lv_obj_set_style_border_opa(round[2], LV_OPA_0, 0);
    lv_obj_set_size(round[2], 8, 8);      /* 设置提示圈大小 */
    lv_obj_align(round[2], LV_ALIGN_CENTER, 20, 150);   /* 距离中心点的相对位置 */

    /* 以透明度提示当前所在tab */
    for(i = 0; i < 3; i++)
    {
        if (i == idx)
        {
            lv_obj_set_style_bg_opa(round[i], LV_OPA_80, 0);
        }
        else
        {
            lv_obj_set_style_bg_opa(round[i], LV_OPA_30, 0);
        }
    }

    return;
}

/* 
 * @brief 创建桌面底部快速访问面板
 * @param parent-父对象
 * @param icon_items-保存ICON信息的数组
 * @param icon_event_cb-事件回调函数
 * @retval    None
 * @note 所有ICON公用一个事件回调函数
 */
static void s_gui_desktop_bottom_panel_create(lv_obj_t *parent, app_icon_item_t *icon_items, lv_event_cb_t icon_event_cb)
{
    uint8_t           i;
    static lv_style_t style_bottom_cont;  /* bottom_cont 样式 */
    static lv_style_t icon_style;          /* 图标的样式 */

    /* bottom_panel 样式初始化 */
    lv_style_init(&style_bottom_cont);    /* fixed icon container 的样式初始化 */
    lv_style_set_pad_all(&style_bottom_cont, 0);
    lv_style_set_bg_opa(&style_bottom_cont, LV_OPA_50);     /* 背景透明度 */
    lv_style_set_border_opa(&style_bottom_cont, LV_OPA_0);  /* 边界透明 */
    lv_style_set_pad_left(&style_bottom_cont, 10);        /* 容器内控件离容器左边距离 */
    lv_style_set_pad_right(&style_bottom_cont, 10);       /* 容器内控件离容器右边距离 */
    lv_style_set_radius(&style_bottom_cont, 22);           /* 圆角化 */
    lv_style_set_flex_main_place(&style_bottom_cont, LV_FLEX_ALIGN_SPACE_EVENLY); /* 平均排列 */
    lv_style_set_layout(&style_bottom_cont, LV_LAYOUT_FLEX);              /* 布局方式弹性布局 */

    /* 创建桌面底部ICON容器 */
    lv_obj_t * bottom_cont = lv_obj_create(parent);
    lv_obj_set_size(bottom_cont, GUI_APP_ICON_SIZE * GUI_APP_COL_NBR, GUI_APP_ICON_SIZE); /* 设置容器尺寸 */
    lv_obj_add_style(bottom_cont, &style_bottom_cont, 0);
    lv_obj_set_scrollbar_mode(bottom_cont, LV_SCROLLBAR_MODE_OFF);                /* 隐藏滚动条 */
    lv_obj_align(bottom_cont, LV_ALIGN_BOTTOM_MID, 0, -10);   /* 离底部 */

    /* icon样式初始化 */
    lv_style_init(&icon_style);

    /* 逐个创建图标 */
    for (i = 0; i < GUI_APP_BOTTOM_PANEL_NBR; i++)
    {
        /* 判断成员是否有效 */
        if ((icon_items[i].img == NULL) || (icon_items[i].app_create == NULL))
        {
            break;  /* 当前页面创建完成 */
        }

        /* 创建控件对象 */
        lv_obj_t *img_icon = lv_img_create(bottom_cont);    /* parent 是 bottom_panel */

        /* 设置图片 */
        lv_img_set_src(img_icon, icon_items[i].img);
        lv_obj_add_flag(img_icon, LV_OBJ_FLAG_CLICKABLE);   /* 图标可点击 */
        lv_obj_add_style(img_icon, &icon_style, 0);
        lv_obj_add_event_cb(img_icon, icon_event_cb, LV_EVENT_CLICKED, NULL);    /* 为图标添加点击事件 */

        /* 将该icon加进app对象链表 */
        s_gui_app_obj_list_append(img_icon);
    }

    return;
}

/* 
 * @brief 创建桌面应用
 * @param parent-父对象
 * @param icon_items-保存ICON信息的数组
 * @param icon_event_cb-事件回调函数
 * @retval    None
 * @note 所有ICON公用一个事件回调函数
 */
static void s_gui_create_tab_icons(lv_obj_t *parent_layout, lv_obj_t *parent, app_icon_item_t *icon_items, lv_event_cb_t icon_event_cb)
{
    uint8_t    i;

    static lv_style_t icon_style;               // 中间图标区域，容器中的图标的样式

    /* 容器中的图标的样式 */
    lv_style_init(&icon_style);
    lv_style_set_text_opa(&icon_style, LV_OPA_0);
    lv_style_set_text_font(&icon_style, &lv_font_montserrat_14);

    /* 逐个创建图标 */
    for (i = 0; i < GUI_APP_NBR_PER_TAB; i++)
    {
        /* 判断成员是否有效 */
        if ((icon_items[i].img == NULL) || (icon_items[i].app_create == NULL))
        {
            break;  /* 当前页面创建完成 */
        }

        /* 创建控件对象 */
        lv_obj_t *img_icon   = lv_img_create(parent_layout);    /* parent 是 container */
        lv_obj_t *label_icon = lv_label_create(parent);

        /* 设置图片 */
        lv_img_set_src(img_icon, icon_items[i].img);
        lv_obj_add_flag(img_icon, LV_OBJ_FLAG_CLICKABLE);   /* 图标可点击 */
        lv_obj_add_style(img_icon, &icon_style, 0);
        lv_obj_add_event_cb(img_icon, icon_event_cb, LV_EVENT_CLICKED, NULL);    /* 为图标添加点击事件 */

        /* 设置文字(显示在按键下方的app名称) */
        lv_label_set_text(label_icon, icon_items[i].text_en);
        lv_obj_set_style_text_color(label_icon, lv_color_hex(0xffffff), 0);
        lv_obj_set_style_text_align(label_icon, LV_TEXT_ALIGN_CENTER, 0);
        lv_obj_align_to(label_icon, img_icon, LV_ALIGN_OUT_BOTTOM_MID, 0, 0);
        lv_obj_move_foreground(label_icon); // 防止被桌面背景图覆盖，将其移到前台

        /* 将该icon加进app对象链表 */
        s_gui_app_obj_list_append(img_icon);
    }

    return;
}

/* 创建桌面 */
void gui_create_desktop(void)
{
    uint8_t  i;
    char     pname[5];
    
    /* 控件 */
    lv_obj_t *img_desktop;
    lv_obj_t *tabview_desktop;
    lv_obj_t *tabs[GUI_APP_TAB_NBR];
    lv_obj_t *tab_conts[GUI_APP_TAB_NBR];

    /* 样式 */
    static lv_style_t style_tabview;    /* tabview 样式 */
    static lv_style_t style_icon_cont;  /* icon_container 样式 */

    /* 样式初始化 */
    lv_style_init(&style_tabview);  /* style_tabview 的样式初始化 */
    lv_style_set_bg_opa(&style_tabview, LV_OPA_0);

    lv_style_init(&style_icon_cont);    /* icon container 的样式初始化 */
    lv_style_set_bg_opa(&style_icon_cont, LV_OPA_0);        /* 背景透明 */
    lv_style_set_border_opa(&style_icon_cont, LV_OPA_0);    /* 边界透明 */
    lv_style_set_pad_column(&style_icon_cont, GUI_APP_ROW_GAP);  /* 竖直两个图标间间隔 */
    lv_style_set_pad_row(&style_icon_cont, GUI_APP_COL_GAP);   /* 水平两个图标间间隔 */
    lv_style_set_layout(&style_icon_cont, LV_LAYOUT_FLEX);              /* 布局方式弹性布局 */
    lv_style_set_flex_flow(&style_icon_cont, LV_FLEX_FLOW_ROW_WRAP);    /* 设置水平内容包裹flow风格 */

    /* 获取当前屏幕 */
    lv_obj_t *scr = lv_disp_get_scr_act(NULL); 

    /* 加载默认壁纸 */
    img_desktop = lv_img_create(scr);
    lv_img_set_src(img_desktop, &wallpaper_img);

    /* 屏幕顶部状态栏区域 */
    s_gui_desktop_top_status_area(scr);

    /* 创建 tabview */
    tabview_desktop = lv_tabview_create(scr, LV_DIR_TOP, 0);        /* 不显示 tab 栏 */
    lv_obj_add_style(tabview_desktop, &style_tabview, 0);           /* 添加style */
    lv_tabview_set_act(tabview_desktop, cur_tab_idx, LV_ANIM_ON);  /* 设置显示当前tab */
    lv_obj_add_event_cb(tabview_desktop, s_gui_tab_idx_event_handler, LV_EVENT_VALUE_CHANGED, NULL);
//    lv_obj_add_event_cb(tabview_desktop, s_gui_tab_scroll_end_handler, LV_EVENT_SCROLL_END, NULL);

    /* 向这个 tabview 添加 tab, 并创建应用icon */
    for (i = 0; i < GUI_APP_TAB_NBR; i++)
    {
        /* 生成tab名 */
        sprintf(pname, "tab %d", i);
        tabs[i] = lv_tabview_add_tab(tabview_desktop, pname);

        /* 创建排列 tab icon 的容器 */
        tab_conts[i] = lv_obj_create(tabs[i]);
        lv_obj_set_size(tab_conts[i], GUI_TAB_APP_HOR_RES, GUI_TAB_APP_VER_RES);    /* 设置容器尺寸 */
        lv_obj_align(tab_conts[i], LV_ALIGN_TOP_MID, 0, GUI_TOP_STATUS_PANEL_HEIGHT);     /* 离顶部距离 */
        lv_obj_add_style(tab_conts[i], &style_icon_cont, 0);
        lv_obj_set_scrollbar_mode(tab_conts[i], LV_SCROLLBAR_MODE_OFF);                /* 隐藏滚动条 */

        /* 逐个创建APP (并在该容器内排列) */
        s_gui_create_tab_icons(tab_conts[i], tabs[i], (app_icon_item_t *) &app_desktop_icons[i][0], 
                               s_gui_app_obj_event_cb);

        /* 创建提示当前tab的提示圆点 */
        s_gui_tab_idx_dot_create(tabs[i], i);
    }

    /* 创建桌面底部快速访问面板 */
    s_gui_desktop_bottom_panel_create(scr, (app_icon_item_t *) &app_panel_icons[0], s_gui_app_obj_event_cb);

    return;
}

/* 主题设置 */
static RET_STATUS s_gui_app_set_theme(GUI_THEME THEME)
{
    RET_STATUS RET = RET_OK;

    /* 根据选择的主题, 设置主题 */
    
    switch (THEME)
    {
        case GUI_THEME_MATERIAL:
            break;

        case GUI_THEME_NIGHT:
        
            break;

        case GUI_THEME_ALIEN:
        
            break;

        case GUI_THEME_ZEN:
        
            break;

        case GUI_THEME_NEMO:
        
            break;

        case GUI_THEME_MONO:
        
            break;

        case GUI_THEME_DEFAULT:
        
            break;

        case GUI_THEME_TEMPL:
                
            break;

        default: break;
    }

    return RET;
}

/* gui主窗口 */
RET_STATUS gui_app_mainwindow(void)
{
    /* 判断文件系统是否挂在成功 */
    if (cmpnt_get_fs_status() != CMPNT_STA_READY)
    {
        rt_kprintf("gui_app_mainwindow fs error\r\n");
        return RET_ERROR;
    }
    
    /* 判断GUI是否完成初始化 */
    if (cmpnt_get_gui_status() != CMPNT_STA_READY)
    {
        rt_kprintf("gui_app_mainwindow gui error\r\n");
        return RET_ERROR;
    }
    
    /* 从文件系统加载字体 */
    if (gui_rsrc_load_font_from_file() != RET_OK)
    {
        return RET_ERROR;
    }

    /* 从文件系统加载所有图片到内存 */
    if (gui_rsrc_load_img_from_file() != RET_OK)
    {
        return RET_ERROR;
    }

    /* 主题设置 */
    if (s_gui_app_set_theme(GUI_THEME_DEFAULT) != RET_OK)
    {
        return RET_ERROR;
    }

    /* 创建桌面 */
    gui_create_desktop();

    /* 创建任务 */

    return RET_OK;
}
